#ifndef TBR_RASTERIZER_HPP
#define TBR_RASTERIZER_HPP

#include "ap_int.h"
#include "ap_fixed.h"
#include "hls_stream.h"
#include "fpal.hpp" // 包含定点数运算逻辑库和 PixelWriteCount
#include "hr_tbr.hpp" // 包含 binned_triangle_packet_fixed, TILE_PIXEL_COUNT 和 TBR 常量

// -----------------------------------------------------------
// DDR AXI Master 接口使用的 64 位数据类型
// -----------------------------------------------------------
typedef ap_uint<64> zbuffer_ddr_word_t;
typedef ap_uint<64> color_ddr_word_t; // 64位字，现在每个字包含两个 32位槽，每个槽存储一个 24位BGR颜色 (低24位)

// -----------------------------------------------------------
// 辅助结构体和常量
// -----------------------------------------------------------
const int Z_PER_WORD = 4; // 64 bits / 16 bits = 4 depth values per word
// 关键修改：每个 64 位字仍然包含 2 个 32 位槽，但每个槽内部只使用 24 位表示 BGR 颜色。
// 这样可以保持 DDR 访问粒度不变 (每次读写 64 位，对应 2 个 32 位地址)，同时满足 BGR 24 位的要求。
const int COLOR_PER_WORD = 2; // 64 bits / 32 bits_slot = 2 color values per word (assuming 24-bit RGB packed into 32-bit slot)

const ap_uint<64> Z_MASK_16BIT = 0xFFFF;
const ap_uint<32> COLOR_MASK_24BIT = 0xFFFFFF; // For 24-bit BGR colors (RRGGBB)
const ap_uint<64> PIXEL_SLOT_MASK = 0xFFFFFFFF; // For 32-bit color slots within 64-bit word (用于清除整个32位槽)


// --- 封装光栅化器配置参数的结构体 ---
struct RasterizerConfig {
    ap_uint<16> num_triangles;
    ap_uint<11> max_x_res;
    ap_uint<11> max_y_res;
    ap_uint<8> num_tiles_x; // 计算出的 tile 数量
    ap_uint<8> num_tiles_y; // 计算出的 tile 数量
};

// -----------------------------------------------------------
// TBR_Rasterizer 模块的主HLS函数声明
// 职责：循环遍历所有 Tiles，对每个 Tile 执行光栅化和深度测试，并将结果写回 DDR。
// -----------------------------------------------------------
void tbr_rasterizer_with_bram_read(
    binned_triangle_packet_fixed all_triangles_bram[MAX_NUM_TRIANGLES], // 共享 BRAM 数组
    hls::stream<TileListDataPacket>& s_tile_list_in, // 从流中读取 Tile List 数据 (现在直接来自 hr_tbr_binning_with_bram_write)
    hls::stream<ap_uint<16>>& s_num_triangles_to_rasterizer, // 接收从 binning 模块转发的三角形总数
    hls::stream<ap_uint<11>>& s_max_x_res_to_rasterizer,                // 最大X分辨率，通过 stream 传递 (现在直接来自 hr_tbr_binning_with_bram_write)
    hls::stream<ap_uint<11>>& s_max_y_res_to_rasterizer,                // 最大Y分辨率，通过 stream 传递 (现在直接来自 hr_tbr_binning_with_bram_write)
    zbuffer_ddr_word_t* output_zbuffer_ddr_write, // Z-buffer (R/W with cache)
    color_ddr_word_t* output_framebuffer_ddr,         // Framebuffer (R/W)
    ap_uint<32>& output_actual_write_ops               // 输出参数，报告实际写入DDR的像素数
);


// -----------------------------------------------------------
// 辅助函数声明 (用于 DATAFLOW 优化)
// -----------------------------------------------------------

// 辅助函数：从流中读取光栅化器配置参数
void read_rasterizer_config(
    hls::stream<ap_uint<16>>& s_num_triangles_to_rasterizer_in,
    hls::stream<ap_uint<11>>& s_max_x_res_to_rasterizer_in,
    hls::stream<ap_uint<11>>& s_max_y_res_to_rasterizer_in,
    RasterizerConfig& config
);


// 辅助函数：将 Tile List 从 stream 写入本地 BRAM
void write_tile_list_to_bram(
    hls::stream<TileListDataPacket>& s_tile_list_in,
    ap_uint<8> num_tiles_x,
    ap_uint<8> num_tiles_y,
    // 因为是 static 数组，所以传递指针或引用
    ap_uint<TILE_LIST_MAX_TRIANGLES_PER_TILE_LOG2> local_tile_list_count[MAX_NUM_TILES_Y][MAX_NUM_TILES_X],
    ap_uint<TRIANGLE_ID_BITS> local_tile_list_data[MAX_NUM_TILES_Y][MAX_NUM_TILES_X][TILE_LIST_MAX_TRIANGLES_PER_TILE]
);

// 辅助函数：处理单个 Tile 的光栅化，输出局部像素写入计数
// 接收 RasterizerConfig 结构体，并通过 stream 输出像素写入计数
void rasterize_single_tile(
    ap_uint<8> tile_y_idx,
    ap_uint<8> tile_x_idx,
    const RasterizerConfig& config, // 使用 RasterizerConfig 结构体
    binned_triangle_packet_fixed all_triangles_bram[MAX_NUM_TRIANGLES],
    // 因为是 static 数组，所以传递指针或引用
    ap_uint<TILE_LIST_MAX_TRIANGLES_PER_TILE_LOG2> local_tile_list_count[MAX_NUM_TILES_Y][MAX_NUM_TILES_X],
    ap_uint<TRIANGLE_ID_BITS> local_tile_list_data[MAX_NUM_TILES_Y][MAX_NUM_TILES_X][TILE_LIST_MAX_TRIANGLES_PER_TILE],
    zbuffer_ddr_word_t* output_zbuffer_ddr_write,
    color_ddr_word_t* output_framebuffer_ddr,
    hls::stream<PixelWriteCount>& s_tile_pixel_write_counts // 输出到 stream
);

// 封装所有 Tile 循环的函数，以符合 DATAFLOW 规范
void process_all_tiles_dataflow(
    const RasterizerConfig& config,
    binned_triangle_packet_fixed all_triangles_bram[MAX_NUM_TRIANGLES],
    ap_uint<TILE_LIST_MAX_TRIANGLES_PER_TILE_LOG2> local_tile_list_count[MAX_NUM_TILES_Y][MAX_NUM_TILES_X],
    ap_uint<TRIANGLE_ID_BITS> local_tile_list_data[MAX_NUM_TILES_Y][MAX_NUM_TILES_X][TILE_LIST_MAX_TRIANGLES_PER_TILE],
    zbuffer_ddr_word_t* output_zbuffer_ddr_write,
    color_ddr_word_t* output_framebuffer_ddr,
    hls::stream<PixelWriteCount>& s_tile_pixel_write_counts // 输出到 stream
);

// 汇总像素写入计数的函数，以符合 DATAFLOW 规范
void sum_pixel_write_counts_dataflow(
    const RasterizerConfig& config,
    hls::stream<PixelWriteCount>& s_tile_pixel_write_counts_in,
    ap_uint<32>& total_actual_writes_to_ddr_out
);


#endif // TBR_RASTERIZER_HPP
